<?php

namespace addons\qingdongams\controller;

use addons\qingdongams\model\File;
use addons\qingdongams\model\Ocr;
use addons\qingdongams\model\OcrType;
use addons\qingdongams\model\AdminConfig;
use fast\Http;
use think\Cache;
use think\Db;
use think\Exception;
use think\Log;

/**
 * 文字识别
 */
class Ocrimg extends StaffApi
{
    protected $noNeedLogin = [];
    protected $noNeedRight = [];
    protected $curl = 'https://aip.baidubce.com/rest/2.0/ocr/v1/';

    // 你的百度 APPID AK SK
    public function _initialize()
    {
        $this->apiKey =AdminConfig::getConfigValue('baidu_api','baidu');
        $this->secretKey =AdminConfig::getConfigValue('baidu_secret','baidu');
        $this->textinappid =AdminConfig::getConfigValue('textin_api','textin');
        $this->textinsecret =AdminConfig::getConfigValue('textin_secret','textin');
        parent::_initialize();
    }

    // 获取识别类型
    public function getTypes()
    {
        $this->success('', OcrType::field('id,name')->select());
    }

    //上传识别
    public function getOcr()
    {
        $params = $this->request->post();
        if (!$params['type_id'] || !$params['file_id']) {
            $this->error('参数缺失');
        }
        $img = cdnurl(File::getUrl($params['file_id']), true);
        $img_type = substr(strrchr($img, '.'), 1);
        if (!in_array($img_type, ['jpg', 'jpeg', 'png', 'bmp'])) {
            $this->error('图片类型不对，请上传jpg/jpeg/png/bmp等格式图片');
        }
        $action = OcrType::where('id', $params['type_id'])->value('action');

        $url = $this->curl . $action . '?access_token=' . $this->getAccessToken();
        $imgcontent = file_get_contents($img);
        $imgcontent = base64_encode($imgcontent);
        $bodys = array(
            'image' => $imgcontent
        );
        $res = Http::post($url, $bodys);
        Log::write('ocr返回结果 ' . $this->auth->id . '----请求：' . $url . '=====:' . $res);
        $result = json_decode($res, true);
        if (isset($result['error_code'])) {
            $this->error($result['error_msg'], null, $result['error_code']);
        }
        $params['ocr_result'] = is_array($res) ? json_encode($res) : $res;
        $data = $this->resultReturn($params['type_id'], $result['words_result']);

        $saveRes = true;
        Db::startTrans();
        try {
            $params['log_id'] = $result['log_id'];
            $params['staff_id'] = $this->auth->id;
            $params['file_url'] = $img;
            $params['money'] = $data['money'] ?? 0;
            $model = new Ocr();
            $saveRes = $model->allowField(true)->save($params);
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($saveRes) {
            $this->success('识别成功', array_merge($data, ['log_id' => $result['log_id']]));
        }
    }

    // 获取accesstoken
    public function getAccessToken()
    {
        $key = 'ocr_token_';
        if ($token = Cache::get($key)) {
            return $token;
        }
        $url = 'https://aip.baidubce.com/oauth/2.0/token';
        $post_data['grant_type'] = 'client_credentials';
        $post_data['client_id'] = $this->apiKey;
        $post_data['client_secret'] = $this->secretKey;
        $o = "";
        foreach ($post_data as $k => $v) {
            $o .= "$k=" . urlencode($v) . "&";
        }
        $post_data = substr($o, 0, -1);
        $res = Http::post($url, $post_data);
        Log::write('ocr获取accestoken: ' . $this->auth->id . '----' . json_encode($post_data) . '===结果：' . $res);
        if (!$res) {
            $this->error('请联系管理员，识别失败!');
        }
        $result = json_decode($res, true);
        if (isset($result['error'])) {
            $this->error('请联系管理员，识别失败!');
        }
        Cache::set($key, $result['access_token'], 2592000);
        return $result['access_token'];
    }


    public function resultReturn($type, $result)
    {
        $data = [];
        switch ($type) {
            case 1:
                //1	增值税发票识别
                $data = [
                    'InvoiceType' => $result['InvoiceType'],// 发票种类
                    'InvoiceTypeOrg' => $result['InvoiceTypeOrg'],// 发票名称
                    'InvoiceCode' => $result['InvoiceCode'],// 发票代码
                    'InvoiceNum' => $result['InvoiceNum'],// 发票号码
                    'InvoiceDate' => $result['InvoiceDate'],// 		开票日期
                    'PurchaserName' => $result['PurchaserName'],// 	购方名称
                    'PurchaserRegisterNum' => $result['PurchaserRegisterNum'],// 	购方纳税人识别号
                    'PurchaserAddress' => $result['PurchaserAddress'],// 	购方地址及电话
                    'PurchaserBank' => $result['PurchaserBank'],// 	购方开户行及账号
                    'Password' => $result['Password'],// 密码区
                    'Province' => $result['Province'],// 	省
                    'City' => $result['City'],// 市
                    'Agent' => $result['Agent'],// 是否代开
                    'CommodityName' => $result['CommodityName'],// 货物名称 ['row':行号，'word'：内容']
                    'CommodityType' => $result['CommodityType'],// 规格型号 ['row':行号，'word'：内容']
                    'CommodityUnit' => $result['CommodityUnit'],// 单位 ['row':行号，'word'：内容']
                    'CommodityNum' => $result['CommodityNum'],// 数量 ['row':行号，'word'：内容']
                    'CommodityPrice' => $result['CommodityPrice'],// 单价 ['row':行号，'word'：内容']
                    'CommodityAmount' => $result['CommodityAmount'],// 金额 ['row':行号，'word'：内容']
                    'CommodityTaxRate' => $result['CommodityTaxRate'],// 税率 ['row':行号，'word'：内容']
                    'CommodityTax' => $result['CommodityTax'],// 税额 ['row':行号，'word'：内容']
                    'CommodityPlateNum' => $result['CommodityPlateNum'] ?? [],// 车牌号 ['row':行号，'word'：内容']
                    'CommodityVehicleType' => $result['CommodityVehicleType'] ?? [],// 类型 ['row':行号，'word'：内容']
                    'CommodityStartDate' => $result['CommodityStartDate'] ?? [],// 通行日期起 ['row':行号，'word'：内容']
                    'CommodityEndDate' => $result['CommodityEndDate'] ?? [],// 通行日期止 ['row':行号，'word'：内容']
                    'OnlinePay' => $result['OnlinePay'] ?? '',// 电子支付标识
                    'SellerName' => $result['SellerName'],// 销售方名称
                    'SellerRegisterNum' => $result['SellerRegisterNum'],// 销售方纳税人识别号
                    'SellerAddress' => $result['SellerAddress'],// 销售方地址及电话
                    'SellerBank' => $result['销售方开户行及账号'],// 销售方地址及电话
                    'TotalAmount' => $result['TotalAmount'],// 合计金额
                    'money' => $result['TotalAmount'],// 合计金额
                    'TotalTax' => $result['TotalTax'],// 合计税额
                    'AmountInWords' => $result['AmountInWords'],// 价税合计(大写)
                    'AmountInFiguers' => $result['AmountInFiguers'],// 价税合计(小写)
                    'NoteDrawer' => $result['NoteDrawer'],// 开票人
                    'Remarks' => $result['Remarks'],// 备注
                ];
                break;
            case 2:
                //2	增值税发票验真
                $data = [
                    'InvoiceType' => $result['InvoiceType'], // 发票类型
                    'InvoiceCode' => $result['InvoiceCode'], // 发票代码
                    'InvoiceNum' => $result['InvoiceNum'], // 发票号码
                    'InvoiceDate' => $result['InvoiceDate'], // 开票日期
                    'AmountInFiguers' => $result['AmountInFiguers'], // 	合计金额小写
                    'money' => $result['AmountInFiguers'],// 合计金额
                    'AmountInWords' => $result['AmountInWords'], // 	合计金额大写
                    'CommodityName' => $result['CommodityName'], // 商品名称 [['word':'餐费','row':1]]
                    'CommodityUnit' => $result['CommodityUnit'], // 商品单位 [['word':'餐费','row':1]]
                ];
                break;
            case 3:
                //3	定额发票识别
                $data = [
                    'invoice_code' => $result['invoice_code'], // 发票代码
                    'invoice_number' => $result['invoice_number'], // 发票号码
                    'invoice_rate' => $result['invoice_code'], // 金额
                    'location' => $result['location'], // 发票所在地
                    'invoice_rate_lowercase' => $result['invoice_rate_lowercase'], // 发票金额小写
                    'money' => $result['invoice_rate_lowercase'],// 合计金额
                    'province' => $result['province'], // 省
                    'city' => $result['city'] ?? '', // 市
                ];
                break;
            case 4:
                //4	通用机打发票识别
                $data = [
                    'InvoiceType' => $result['InvoiceType'],// 发票种类
                    'InvoiceCode' => $result['InvoiceCode'],// 发票代码
                    'InvoiceNum' => $result['InvoiceNum'],// 发票号码
                    'InvoiceDate' => $result['InvoiceDate'],// 		开票日期
                    'AmountInWords' => $result['AmountInWords'],// 		合计金额大写
                    'AmountInFiguers' => $result['AmountInFiguers'],// 	合计金额小写
                    'money' => $result['AmountInFiguers'],// 合计金额
                    'CommodityName' => $result['CommodityName'],// 货物名称 ['row':行号，'word'：内容']
                    'CommodityUnit' => $result['CommodityUnit'],// 商品单位 ['row':行号，'word'：内容']
                    'CommodityPrice' => $result['CommodityPrice'],// 商品单价 ['row':行号，'word'：内容']
                    'CommodityNum' => $result['CommodityNum'],// 商品数量 ['row':行号，'word'：内容']
                    'CommodityAmount' => $result['CommodityAmount'],// 	商品金额 ['row':行号，'word'：内容']
                    'IndustrySort' => $result['IndustrySort'],// 	行业分类
                    'MachineNum' => $result['MachineNum'],// 		机打号码
                    'CheckCode' => $result['CheckCode'],// 		校验码
                    'SellerName' => $result['SellerName'],// 			销售方名称
                    'SellerRegisterNum' => $result['SellerRegisterNum'],// 			销售方纳税人识别号
                    'PurchaserName' => $result['PurchaserName'],// 			购买方名称
                    'PurchaserRegisterNum' => $result['PurchaserRegisterNum'],// 				购买方纳税人识别
                    'TotalTax' => $result['TotalTax'],// 				合计税额
                    'Province' => $result['Province'],    // 省
                    'City' => $result['City'],       // 市
                ];
                break;
            case 5:
                //5	火车票识别
                $data = [
                    'ticket_num' => $result['ticket_num'], // 车票号
                    'starting_station' => $result['starting_station'], // 	始发站
                    'train_num' => $result['train_num'], // 车次号
                    'destination_station' => $result['destination_station'], // 到达站
                    'date' => $result['date'], // 出发日期
                    'ticket_rates' => $result['ticket_rates'], // 车票金额
                    'money' => $result['ticket_rates'],// 合计金额
                    'seat_category' => $result['ticket_rates'], // 席别
                    'name' => $result['name'], // 乘客姓名
                    'id_num' => $result['id_num'], // 身份证号
                    'serial_number' => $result['serial_number'], // 序列号
                    'sales_station' => $result['sales_station'], // 售站
                    'time' => $result['time'], // 时间
                    'seat_num' => $result['seat_num'], // 座位号
                ];
                break;
            case 6:
                //6	出租车票识别
                $data = [
                    'InvoiceCode' => $result['InvoiceCode'], // 发票代号
                    'InvoiceNum' => $result['InvoiceNum'], // 发票号码
                    'TaxiNum' => $result['TaxiNum'], // 车牌号
                    'Date' => $result['Date'], // 日期
                    'Time' => $result['Time'], // 上下车时间
                    'PickupTime' => $result['PickupTime'], // 上车时间
                    'DropoffTime' => $result['DropoffTime'], // 下车时间
                    'Fare' => $result['Fare'], // 	金额
                    'money' => $result['Fare'],// 合计金额
                    'FuelOilSurcharge' => $result['FuelOilSurcharge'], // 		燃油附加费
                    'CallServiceSurcharge' => $result['CallServiceSurcharge'], // 	叫车服务费
                    'TotalFare' => $result['TotalFare'], // 	总金额
                    'Location' => $result['Location'], // 	开票城市
                    'PricePerkm' => $result['PricePerkm'], // 		单价
                    'Distance' => $result['Distance'], // 		里程
                    'province' => $result['province'] ?? '', // 省
                    'city' => $result['city'] ?? '', // 市
                ];
                break;
            case 7:
                //7	飞机行程单识别
                $data = [
                    'name' => $result['name'],    // 		里程
                    'starting_station' => $result['starting_station'], // 			始发站
                    'destination_station' => $result['destination_station'], // 			目的站
                    'flight' => $result['flight'], // 		航班号
                    'date' => $result['date'],   // 			日期
                    'ticket_number' => $result['ticket_number'], // 				电子客票号码
                    'fare' => $result['fare'],    // 			票价
                    'money' => $result['fare'],//
                    'dev_fund' => $result['dev_fund'], // 			民航发展基金/基建费
                    'fuel_surcharge' => $result['fuel_surcharge'], // 				燃油附加费
                    'other_tax' => $result['其他税费'],        // 	民航发展基金/基建费
                    'ticket_rates' => $result['ticket_rates'],   // 合计金额
                    'issued_date' => $result['issued_date'],    // 填开日期
                    'id_num' => $result['id_num'],        // 身份证号
                    'carrier' => $result['carrier'],       // 承运人
                    'time' => $result['time'],          // 时间
                    'issued_by' => $result['issued_by'],     // 	订票渠道
                    'serial_number' => $result['serial_number'], // 		印刷序号
                    'insurance' => $result['insurance'],     // 	保险费
                    'fare_basis' => $result['fare_basis'],    // 	客票级别
                    'class' => $result['class'],         // 	座位等级
                    'agent_code' => $result['agent_code'],    // 	销售单位号
                    'endorsement' => $result['endorsement'],   // 		签注
                    'allow' => $result['allow'],        // 		免费行李
                ];
                break;
            case 8:
                //8	汽车票识别
                $data = [
                    'InvoiceCode' => $result['InvoiceCode'], // 发票代码
                    'InvoiceNum' => $result['InvoiceNum'], // 发票号码
                    'Date' => $result['Date'], // 日期
                    'Time' => $result['Time'], // 时间
                    'StartingStation' => $result['StartingStation'], // 出发站
                    'Fare' => $result['Fare'], // 	金额
                    'money' => $result['fare'],//
                    'IdNum' => $result['IdNum'], // 身份证号
                    'DestinationStation' => $result['DestinationStation'], // 到达站
                    'Name' => $result['Name'], // 姓名
                    'InvoiceTime' => $result['InvoiceTime'], // 	开票日期
                ];
                break;
            case 9:
                //9	过路过桥费发票识别
                $data = [
                    'InvoiceCode' => $result['InvoiceCode'], // 发票代码
                    'InvoiceNum' => $result['InvoiceNum'], // 发票号码
                    'Entrance' => $result['Entrance'], // 	入口
                    'Exit' => $result['Exit'], // 出口
                    'Date' => $result['Date'], // 日期
                    'Time' => $result['Time'], // 时间
                    'Fare' => $result['Fare'], // 	金额
                    'money' => $result['fare'],//
                    'province' => $result['province'] ?? '', // 省
                    'city' => $result['city'] ?? '', // 市
                ];
                break;
            case 10:
                //10	船票识别
                $data = [
                    'InvoiceType' => $result['InvoiceType'], // 发票类型
                    'InvoiceCode' => $result['InvoiceCode'], // 发票代码
                    'InvoiceNum' => $result['InvoiceNum'], // 发票号码
                    'StartingStation' => $result['StartingStation'], // 出发地点
                    'DestinationStation' => $result['DestinationStation'], // 到达地点
                    'Fare' => $result['Fare'], // 	金额
                    'money' => $result['fare'],//
                    'InvoiceDate' => $result['InvoiceDate'], // 	开票日期
                ];
                break;
            case 11:
                //11	网约车行程单识别
                $data = [
                    'ServiceProvider' => $result['ServiceProvider'], // 服务商
                    'StartTime' => $result['StartTime'], // 行程开始时间
                    'EndTime' => $result['EndTime'], // 行程结束时间
                    'Phone' => $result['Phone'], // 行程人手机号
                    'ApplicationDate' => $result['ApplicationDate'], // 申请日期
                    'TotalFare' => $result['TotalFare'], // 总金额
                    'City' => $result['City'], // 城市
                    'Fare' => $result['Fare'], // 金额
                    'money' => $result['fare'],//
                    'Items' => $result['Items'], // [['PickupTime'=>上车时间,'PickupDate'=>上车日期,'CarType'=>车型,'Distance'=>里程,'StartPlace'=>起点,'DestinationPlace'=>终点]]
                ];
                break;
            case 12:
                //12	通用票据识别
                $data = [
                    ['location' => $result['location'],// [['left'=>'','top'=>'','width'=>'','height'=>'']]
                        'words' => $result['words']],// 识别结果字符串
                ];
                break;
            case 13:
                //	车牌
                $data = ['number' => $result['number'],// 识别结果字符串
                ];
                break;
            case 14:
                //	名片
                $data = [
                    'name' => $result['NAME'][0],
                    'mobile' => $result['MOBILE'][0],
                    'company' => $result['COMPANY'][0],
                    'addr' => $result['ADDR'][0],
                    'email' => $result['EMAIL'][0],
                    'tel' => $result['TEL'][0],

                ];
                break;
            default:
                break;
        }
        return $data;
    }

    //名片识别  https://www.textin.com/market/detail/business_card
    public function business_card(){
        $file_id=input('file_id');
        if(empty($file_id)){
            $this->error('图片不能为空');
        }
    // 请登录后前往 “工作台-账号设置-开发者信息” 查看 x-ti-app-id
        $app_id = $this->textinappid;
        if(empty($app_id)){
            $this->error('后台未设置textinappid，请联系管理员');
        }
    // 请登录后前往 “工作台-账号设置-开发者信息” 查看 x-ti-secret-code
        $secret_code = $this->textinsecret;
        if(empty($app_id)){
            $this->error('后台未设置textinsecret，请联系管理员');
        }
    // 名片识别
        $url = 'https://api.textin.com/robot/v1.0/api/business_card';
        $img=File::getUrl($file_id);
        $headers = [
            'x-ti-app-id:' . $app_id,
            'x-ti-secret-code:' .  $secret_code
        ];
        $fileData = file_get_contents('.'.$img); // 读取文件
        $response = $this->post($url, $headers, $fileData);
        $ocrResult = json_decode($response, true);
        Log::info($ocrResult);
        // 获取 身份证号 和 姓名
        $result =isset( $ocrResult['result'] )? $ocrResult['result'] : '';
        if ($result)
        {
            $list = $result['item_list'];
            $data=[];
            foreach ($list as $v){
                $data[$v['key']]=['name'=>$v['description'],'value'=>$v['value']];
            }
            $textin_field =AdminConfig::getConfigValue('textin_field','textin');
            if($textin_field){
                $textin_field=json_decode($textin_field,true);
            }else{
                $textin_field=[];
            }
            $result=[];
            foreach ($textin_field as $field => $val) {
                if (isset($data[$field]) && $val) {
                    $result[$val] = $data[$field];
                }
            }
            $this->success('请求成功',$result);
        }
        $this->error('识别失败');
    }

    /**
     * Post请求
     *
     * @param string $url 地址
     * @param array $headers Http Header
     * @param string $body 内容
     * @return string
     */
    function post($url, $headers, $body) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }

}
